#include "can_config.h"
#include "command_type.h"

CANConfig::CANConfig()
{
    mutex = PTHREAD_MUTEX_INITIALIZER;
}

CANConfig::~CANConfig()
{
	pthread_mutex_destroy(&mutex);
	close(devHandle);
}

int CANConfig::init(char *dev)
{
	int ret;
    struct can_filter rfilter[1];

	devHandle = socket(PF_CAN, SOCK_RAW, CAN_RAW); //创建套接字
	if(devHandle < 0)
	{
		perror("Open socket error");
		return -1;
	}
	strcpy(ifr.ifr_name, dev);
	ioctl(devHandle, SIOCGIFINDEX, &ifr); //指定 can0 设备
	addr.can_family = AF_CAN;
	addr.can_ifindex = ifr.ifr_ifindex;

	ret = bind(devHandle, (struct sockaddr *)&addr, sizeof(addr)); //将套接字与 can0 绑定
	if(ret < 0)
	{
		perror("CAN bind error");
		return -1;
	}
	// //定义接收规则,只接收表示符等于 0x11 的报文
	// rfilter[0].can_id = 0x11;
	// rfilter[0].can_mask = CAN_SFF_MASK;
	// //设置过滤规则
	// setsockopt(devHandle, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(rfilter));
	// 初始化信号量
    sem_init(&tSem, 0, 0);
	pthread_mutex_init(&mutex, NULL);

	// 创建线程
    ret = pthread_create(&tSensorThread, NULL, &ListenThread, this);
    if (ret != 0) 
    {
        printf("Thread creation failed.\n");
        return -1;
    }

	return 0;
}

void CANConfig::exit(void)
{
    close(devHandle);
}

void* CANConfig::ListenThread(void* arg)
{
	int ret;
	struct can_frame frame;
	CANConfig *pCANConfig = (CANConfig *)arg;

	while(1)
	{
		ret = read(pCANConfig->devHandle, &frame, sizeof(frame));
		//接收报文//显示报文
		if(ret > 0)
		{
			pthread_mutex_lock(&pCANConfig->mutex);
			memcpy(&pCANConfig->recBuf[pCANConfig->iWritePos], &frame, sizeof(frame));
			pCANConfig->iWritePos++;
			if(pCANConfig->iWritePos >= CAN_REC_BUFFER_DEPTH)
			{
				pCANConfig->iWritePos = 0;
			}
			pthread_mutex_unlock(&pCANConfig->mutex);
			// printf("Rec:0x%X\tdata:%x %x %x %x %x %x %x %x\n",frame.can_id, frame.data[0], frame.data[1], \
			// 	frame.data[2], frame.data[3], frame.data[4], frame.data[5], frame.data[6], frame.data[7]);
			sem_post(&pCANConfig->tSem); // 发送信号量;
		}
	}
}

int CANConfig::send(unsigned int id, unsigned char *pData, unsigned char len)      //虚函数的重写
{
	struct can_frame frame;
	int ret;

    frame.can_id = id;
	frame.can_dlc = len;
  
	for(int i = 0; i < len; i++)
	{
		frame.data[i] = pData[i];
	}

	// printf("Send:0x%X\tdata:%x %x %x %x %x %x %x %x\n",frame.can_id, frame.data[0], frame.data[1], \
	// 	frame.data[2], frame.data[3], frame.data[4], frame.data[5], frame.data[6], frame.data[7]);

    ret = write(devHandle, &frame, sizeof(frame));
    if(ret != sizeof(frame))
    {
        printf("Send Error %d\n!", ret);
        return -1; 				//发送错误,退出
    }

	return 0;
}

int CANConfig::getRecive(struct can_frame *frame)
{
	struct timespec ts;

	// 设置超时时间
    clock_gettime(CLOCK_REALTIME, &ts);
    ts.tv_sec += 10; // 5秒后超时
	if(sem_timedwait(&tSem, &ts) < 0) // 线程等待信号量;
	{
		return -1;
	}

	pthread_mutex_lock(&mutex);
	// printf("get:0x%X\tdata:%x %x %x %x %x %x %x %x\n",recBuf[iReadPos].can_id, recBuf[iReadPos].data[0], recBuf[iReadPos].data[1], \
	// recBuf[iReadPos].data[2], recBuf[iReadPos].data[3], recBuf[iReadPos].data[4], recBuf[iReadPos].data[5], recBuf[iReadPos].data[6], recBuf[iReadPos].data[7]);
	memcpy(frame, &recBuf[iReadPos], sizeof(struct can_frame));
	iReadPos++;
	if(iReadPos >= CAN_REC_BUFFER_DEPTH)
	{
		iReadPos = 0;
	}
	pthread_mutex_unlock(&mutex);

	return 0;
}

void CANConfig::clearBuf()
{
	pthread_mutex_lock(&mutex);
	iReadPos = 0;
	iWritePos = 0;
	pthread_mutex_unlock(&mutex);
}

